package com.wjy.sfhcore.engine;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.widget.ProgressBar;

import com.wjy.sfhcore.util.LogUtils;
import com.wjy.sfhcore.util.Tools;

import org.json.JSONException;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;

/**
 * Http协议工具类
 *
 * @author wjy
 */
public class HttpUtil {
    /**
     * HttpUtil对象
     */
    private static HttpUtil instance = new HttpUtil();

    /**
     * 私有化构造器
     */
    private HttpUtil() {
    }

    /**
     * 获取HttpUtil对象
     *
     * @return HttpUtil对象
     */
    public static HttpUtil getInstance() {
        return instance;
    }


    /**
     * HttpPost
     *
     * @param url    地址
     * @param params 参数
     * @return JSONObject对象
     * @throws JSONException
     * @throws Exception
     */
    public String httpPost(String url, Map<String, String> params, byte[] b)
            throws Exception {
        return httpPost(url, params, b);
    }

    /**
     * HttpPost上传文件
     *
     * @param url        地址
     * @param params     Header参数
     * @param bodyParams Body参数
     * @param filePath   文件路径
     * @return
     * @throws Exception
     */
    public String httpPost(String url, Map<String, String> params,
                           Map<String, String> bodyParams, String filePath) throws Exception {
        return httpPost(url, params, bodyParams,
                filePath);
    }

    /**
     * 对url带中文参数进行URLEncoder.encode()
     */
    private String getEncodeUrl(String url) {
        if (url.indexOf("?") != -1) {
            String urlPath = url.substring(0, url.indexOf("?"));
            String urlParams = url.substring(url.indexOf("?") + 1, url.length());
            String paramsKey, paramsValue;
            String[] paramsArray = urlParams.toString().split("&");
            StringBuilder params = new StringBuilder();
            for (int j = 0; j < paramsArray.length; j++) {
                if (paramsArray[j].indexOf("=") != -1) {
                    paramsKey = paramsArray[j].substring(0, paramsArray[j].indexOf("="));
                    paramsValue = paramsArray[j].substring(paramsArray[j].indexOf("=") + 1, paramsArray[j].length());
                    if (Tools.isContainChinese(paramsValue.toString())) {
                        try {
                            params.append(paramsKey).append("=").append(URLEncoder.encode(paramsValue, "UTF-8"));
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                            params.append(paramsKey).append("=").append(paramsValue);
                        }
                    } else {
                        params.append(paramsKey).append("=").append(paramsValue);
                    }
                } else {
                    params.append(paramsArray[j]);
                }
                if (j != paramsArray.length - 1) {
                    params.append("&");
                }
            }
            LogUtils.d("urlPath:" + urlPath + "?params:" + params);
            return urlPath + "?" + params;
        }

        return url;
    }

    /**
     * HttpGet方式
     *
     * @param url    地址
     * @param params 参数
     * @return Json字符串
     * @throws Exception
     */
    @SuppressLint("UseValueOf")
    public String httpGet(String url, Map<String, String> params) throws Exception {
        URL mUrl = new URL(getEncodeUrl(url));
        HttpURLConnection conn = (HttpURLConnection) mUrl.openConnection();

        String result = null;
        conn.setRequestMethod("GET");
        int statusCode;
        if (params != null) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                conn.setRequestProperty(entry.getKey(), entry.getValue());
            }
        }
        conn.setConnectTimeout(60 * 1000);
        conn.setReadTimeout(60 * 1000);
        try {
            statusCode = conn.getResponseCode();
            if (statusCode >= 200 && statusCode < 300) {
                // 处理返回的httpResponse信息
                result = retrieveInputStream(conn.getInputStream());
            } else {
                result = retrieveInputStream(conn.getInputStream());
            }

            LogUtils.e("log", url + "\n " + result);

        } catch (SocketTimeoutException e) {
            /*BaseEntity entity = new BaseEntity();
            entity.message = "请求超时";
            entity.result = "-1";
            return JSON.toJSONString(entity);*/
        } finally {
            conn.disconnect();
        }

        return result;
    }

    /**
     * HttpPost
     *
     * @param url    地址
     * @param params 参数
     * @param obj    post对象
     * @return json字符串
     * @throws Exception
     */
    @SuppressLint("UseValueOf")
    public String httpPost(String url, Map<String, String> params,
                           Object obj) throws Exception {
        URL mUrl = new URL(url);
        HttpURLConnection conn = (HttpURLConnection) mUrl.openConnection();

        String result = null;
        int statusCode;
        conn.setRequestMethod("POST");
        if (params != null) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                conn.setRequestProperty(entry.getKey(), entry.getValue());
            }
        }

        conn.setConnectTimeout(60 * 1000);
        conn.setReadTimeout(60 * 1000);
        conn.setDoOutput(true);
        try {
            StringBuffer params_byte = getBodyParams(obj);
            conn.getOutputStream().write(params_byte.toString().getBytes("UTF-8"));
            statusCode = conn.getResponseCode();
            if (statusCode >= 200 && statusCode < 300) {
                /*if (url.contains("/check_vcode")) {
                    saveCookie(conn);
                }*/
                // 处理返回的httpResponse信息
                result = retrieveInputStream(conn.getInputStream());
            } else {
                result = retrieveInputStream(conn.getInputStream());
            }

            LogUtils.d(url + "?" + params_byte.toString());
            LogUtils.e(url, result);
        } catch (SocketTimeoutException e) {
            /*BaseEntity entity = new BaseEntity();
            entity.message = "请求超时";
            entity.result = "-1";
            return JSON.toJSONString(entity);*/
        } finally {
            conn.disconnect();
        }
        return result;
    }

   /* private void saveCookie(HttpURLConnection conn) {
        Map<String, List<String>> headerFields = conn.getHeaderFields();
        Set<Map.Entry<String, List<String>>> entrySet = headerFields.entrySet();
        Iterator<Map.Entry<String, List<String>>> iterator = entrySet.iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, List<String>> next = iterator.next();
            if (next.getKey()!=null && next.getKey().contains("Cookie")) {
                String cookie = next.getValue().get(0);
                if (!Tools.isEmpty(cookie)) {
                    MyApplication.getInstance().sharedPreferencesFactory
                            .setCookie(cookie);
                    break;
                }
            }
        }
    }*/


    /**
     * HttpPost
     *
     * @param url    地址
     * @param params 参数
     * @param client DefaultHttpClient对象
     * @return json字符串
     * @throws Exception
     *//*
    @SuppressLint("UseValueOf")
    private String httpPost(String url, Map<String, String> params,
                            DefaultHttpClient client, byte[] b) throws Exception {
        String result = null;
        int statusCode = 0;
        HttpPost post = new HttpPost(url);
        for (Map.Entry<String, String> entry : params.entrySet()) {
            System.out.println(entry.getKey() + "=" + entry.getValue());
            post.addHeader(entry.getKey(), entry.getValue());
        }

        post.getParams()
                .setParameter("http.socket.timeout", new Integer(30000));

        try {
            ByteArrayEntity entity = new ByteArrayEntity(b);
            post.setEntity(entity);
            HttpResponse r = client.execute(post);
            statusCode = r.getStatusLine().getStatusCode();
            if (statusCode >= 200 && statusCode < 300) {
                // 处理返回的httpResponse信息
                result = retrieveInputStream(r.getEntity());
            } else {
                result = retrieveInputStream(r.getEntity());
            }
            System.out.println("url=" + url + "\nresult=" + result);
        } catch (Exception e) {
            e.printStackTrace();
            new Exception(e);
        } finally {
            post.abort();
        }

        return result;
    }*/

   /* *//**
     * HttpPost
     *
     * @param url    地址
     * @param params 参数
     * @param client DefaultHttpClient对象
     * @param byte[] 图片字节数组
     * @return json字符串
     * @throws Exception
     *//*
    @SuppressLint("UseValueOf")
    private String httpPost(String url, Map<String, String> params,
                            Map<String, String> bodyParams, DefaultHttpClient client,
                            String filePath) throws Exception {
        String result = null;
        int statusCode = 0;
        HttpPost post = new HttpPost(url);
        for (Map.Entry<String, String> entry : params.entrySet()) {
            System.out.println(entry.getKey() + "=" + entry.getValue());
            post.addHeader(entry.getKey(), entry.getValue());
        }

        post.getParams()
                .setParameter("http.socket.timeout", new Integer(30000));
        try {
            MultipartEntity entity = new MultipartEntity();

            for (Map.Entry<String, String> entry : bodyParams.entrySet()) {
                System.out.println(entry.getKey() + "=" + entry.getValue());
                entity.addPart(entry.getKey(), new StringBody(entry.getValue()));
            }

            File file = new File(filePath);
            if (file.exists()) {
                entity.addPart("file", new FileBody(file));
            }

            post.setEntity(entity);
            HttpResponse r = client.execute(post);
            statusCode = r.getStatusLine().getStatusCode();
            if (statusCode >= 200 && statusCode < 300) {
                // 处理返回的httpResponse信息
                result = retrieveInputStream(r.getEntity());
            } else {
                result = retrieveInputStream(r.getEntity());
            }
            System.out.println("url=" + url + "\nresult=" + result);
        } catch (Exception e) {
            e.printStackTrace();
            new Exception(e);
        } finally {
            post.abort();
        }

        return result;
    }*/

    /**
     * 处理httpResponse信息,返回String
     *
     * @return String
     */
    protected String retrieveInputStream(InputStream is) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int i = -1;
        while ((i = is.read()) != -1) {
            baos.write(i);
        }
        return baos.toString();
    }

    private StringBuffer getBodyParams(Object obj) {
        StringBuffer sb = new StringBuffer();
        if (obj != null) {
            Class<?> cls = obj.getClass();
            for (int i = 0; i < cls.getFields().length; i++) {
                try {
                    Field field = cls.getFields()[i];
                    Object fieldValue = field.get(obj);
                    if (fieldValue != null) {
                        sb.append(field.getName()).append("=").append(fieldValue.toString()).append("&");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    continue;
                }
            }
        }

        return sb;
    }

    /**
     * 下载某个path对应的文件
     *
     * @param path    地址
     * @param handler 监控器
     * @return 文件对象
     * @throws Exception
     */
    public File downfile(String path, ProgressBar pb, Handler handler)
            throws Exception {
        File file = null;
        URL url = new URL(path);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setConnectTimeout(60 * 1000);
        conn.setRequestMethod("GET");

        int length = conn.getContentLength();
        int code = conn.getResponseCode();
        if (code >= 200 && code < 300) {
            pb.setMax(length);

            InputStream is = conn.getInputStream();
            int index = path.lastIndexOf("/") + 1;

            String filename = path.substring(index, path.length());
            file = new File(Environment.getExternalStorageDirectory(), filename);
            FileOutputStream fos = new FileOutputStream(file);

            byte[] buffer = new byte[1024];
            int len = 0;
            int total = 0;

            // 格式化APK总大小
            String formatTotal = String.valueOf((double) length / 1024 / 1024);
            int start = formatTotal.indexOf(".");
            formatTotal = formatTotal.substring(0, start + 2);
            while ((len = is.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
                total += len;
                pb.setProgress(total);

                // 显示当前进度百分比
                int percent = (int) Math.floor((double) total / length * 100);

                Message msg = Message.obtain();
                Bundle bundle = new Bundle();
                bundle.putString("percent", percent + "%");
                bundle.putInt("currentLength", total);
                bundle.putInt("totalLength", length);
                msg.what = 3;
                msg.setData(bundle);
                handler.sendMessage(msg);
            }
            fos.flush();
            fos.close();
            is.close();
        }
        return file;
    }
}
